<!--
 * @Author: liushengyan
 * @Date: 2022-07-14 15:47:09
 * @LastEditTime: 2022-07-15 17:32:58
 * @LastEditors: liushengyan
 * @Descripttion: 
-->
<template>
  <div class="compress_file_zip_container">
    <el-card class="upload_container">
      <el-upload
        class="upload_div"
        drag
        action="#"
        multiple
        :auto-upload="false"
        v-model:file-list="uploadFileList"
      >
        <el-icon style="font-size: 40px"> <i-ep-UploadFilled /></el-icon>
        <div class="el-upload__text">拖拽到此处上传 <em>或点击上传</em></div>
      </el-upload>

      <el-form style="margin-top: 20px" :model="form" label-width="100px">
        <el-form-item label="文件名">
          <el-input v-model="form.fileName" type="text">
            <template #append>.zip</template>
          </el-input>
        </el-form-item>
        <el-form-item label="密码">
          <el-input v-model="form.password" type="password" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="compressFile"> 压缩文件 </el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script setup>
import * as zip from "@zip.js/zip.js";

const uploadFileList = ref([]);

const form = reactive({ fileName: "download", password: "" });

const compressFile = async () => {
  if (uploadFileList.value.length == 0) {
    ElMessage({
      message: "请添加文件",
      type: "error",
    });
    return;
  }

  const controller = new AbortController();
  const signal = controller.signal;
  var zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"));

  const loading = ElLoading.service({
    target: document.querySelector(".upload_container"),
    lock: true,
    background: "rgba(0, 0, 0, 0.1)",
    text: "正在压缩",
  });

  await Promise.all(
    uploadFileList.value.map(async (file) => {
      return await zipWriter.add(file.name, new zip.BlobReader(file.raw), {
        bufferedWrite: true,
        password: form.password,
        signal,
        zipCrypto: true,
        onprogress: (index, max) => {
          const percent = parseInt((index / max) * 100 || 0);
          loading.setText(`正在压缩文件  ${file.name} ，进度为${percent}%`);
        },
      });
    })
  )
    .then(async () => {
      let url = URL.createObjectURL(await zipWriter.close());
      const link = document.createElement("a");
      link.style.display = "none";
      link.href = url;
      link.setAttribute("download", `${form.fileName}.zip`);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      uploadFileList.value = [];
    })
    .finally(() => {
      if (loading) {
        loading.close();
      }
    });
};
</script>
<style lang="scss" scoped>
.compress_file_zip_container {
  width: 80%;
  height: 80%;
  padding: 20px;
  background: white;
  .upload_container {
    width: 40%;
    .upload_div {
      max-height: 330px;
      :deep(.el-upload-list--text) {
        max-height: 150px;
        overflow: auto;
      }
    }
  }
}
</style>
